﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;

namespace Extensions
{
    /// <summary>
    /// 枚举扩展方法
    /// </summary>
    /// <remarks></remarks>
    public static class EnumExtensions
    {
        /// <summary>
        /// 获取枚举的描述
        /// </summary>
        /// <param name="enum">枚举值</param>
        /// <returns>description</returns>
        public static string ToDescription(this Enum @enum)
        {
            MemberInfo[] member = @enum.GetType().GetMember(@enum.ToString());
            if (member.Length != 0)
            {
                string description = GetDescription(member[0]);
                if (description != null)
                {
                    return description;
                }
            }
            return @enum.ToString();
        }

        /// <summary>
        /// 将String转化为Enum
        /// </summary>
        /// <typeparam name="TEnum">枚举类型</typeparam>
        /// <param name="value">参数</param>
        /// <remarks>转化失败，将返回抛出异常</remarks>
        /// <returns>枚举值</returns>
        public static TEnum ToEnum<TEnum>(this string value) where TEnum : struct
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                throw new ArgumentNullException("转化的参数value不能为空");
            }
            return Enum.Parse<TEnum>(value);
        }

        /// <summary>
        /// 将String转化为Enum,如果不存在返回默认值
        /// </summary>
        /// <typeparam name="TEnum">枚举类型</typeparam>
        /// <param name="value">参数</param>
        /// <remarks>转化失败，将返回默认值（0）</remarks>
        /// <returns>枚举值</returns>
        public static TEnum ToEnumOrDefault<TEnum>(this string value) where TEnum : struct
        {
            Enum.TryParse<TEnum>(value, out var result);
            return result;
        }

        /// <summary>
        /// 转换成列表
        /// </summary>
        /// <param name="enum">任意枚举值</param>
        /// <returns>List</returns>
        public static List<string> ToList(this Enum @enum)
        {
            return new List<string>(Enum.GetNames(@enum.GetType()));
        }

        /// <summary>
        /// 转换成列表
        /// </summary>
        /// <typeparam name="Type">枚举类型</typeparam>
        /// <returns>List</returns>
        public static List<string> ToList<Type>()
        {
            var type = typeof(Type);
            if (!type.IsEnum)
            {
                throw new TypeAccessException("不是枚举类型");
            }
            return Enum.GetNames(type).ToList();
        }

        /// <summary>
        /// 判断是否存在在枚举中
        /// </summary>
        /// <typeparam name="TEnum">枚举类型</typeparam>
        /// <param name="value">需要判断参数</param>
        /// <returns>true：存在；false：不存在</returns>
        public static bool IsExists<TEnum>(object value)
        {
            return Enum.IsDefined(typeof(TEnum), value);
        }

        /// <summary>
        /// 判断是否存在在枚举中
        /// </summary>
        /// <param name="enum">具体的枚举值</param>
        /// <param name="value">需要判断参数</param>
        /// <returns>true：存在；false：不存在</returns>
        public static bool IsExists(this Enum @enum, object value)
        {
            return Enum.IsDefined(@enum.GetType(), value);
        }

        /// <summary>
        /// 获取成员信息的 Description
        /// </summary>
        /// <param name="memberInfo">成员信息</param>
        /// <returns>Description</returns>
        private static string GetDescription(MemberInfo memberInfo)
        {
            var type = typeof(DescriptionAttribute);
            var attribute = memberInfo.GetCustomAttribute(type) as DescriptionAttribute;
            return attribute?.Description;
        }
    }
}